import React, { useEffect, useRef, useState, useCallback } from 'react';
import { listen, UnlistenFn } from '@tauri-apps/api/event';
import { TerminalComponentProps } from '../types';

// Terminal themes
const themes = {
    dark: {
        background: '#1e1e1e',
        foreground: '#ffffff',
        cursor: '#ffffff',
        selectionBackground: '#264f78',
        black: '#000000',
        red: '#cd3131',
        green: '#0dbc79',
        yellow: '#e5e510',
        blue: '#2472c8',
        magenta: '#bc3fbc',
        cyan: '#11a8cd',
        white: '#e5e5e5',
        brightBlack: '#666666',
        brightRed: '#f14c4c',
        brightGreen: '#23d18b',
        brightYellow: '#f5f543',
        brightBlue: '#3b8eea',
        brightMagenta: '#d670d6',
        brightCyan: '#29b8db',
        brightWhite: '#e5e5e5',
    }
};

export function TerminalXTerm({
    terminal: terminalProps,
    onInput,
    onResize,
    onClose,
    onRename,
}: TerminalComponentProps) {
    const terminalRef = useRef<HTMLDivElement>(null);
    const terminalInstanceRef = useRef<any>(null);
    const fitAddonRef = useRef<any>(null);
    const unlistenFn = useRef<UnlistenFn | null>(null);
    const [loaded, setLoaded] = useState(false);
    const [isEditing, setIsEditing] = useState(false);
    const [editName, setEditName] = useState(terminalProps.name || '');
    const [isClient, setIsClient] = useState(false);

    // Check if we're on client side
    useEffect(() => {
        setIsClient(true);
    }, []);

    // Initialize terminal with xterm
    useEffect(() => {
        if (!terminalRef.current || !isClient || terminalInstanceRef.current) return;

        const initializeTerminal = async () => {
            try {
                // Dynamically import xterm modules
                const [
                    { Terminal },
                    { FitAddon },
                    { WebLinksAddon },
                    { ImageAddon }
                ] = await Promise.all([
                    import('@xterm/xterm'),
                    import('@xterm/addon-fit'),
                    import('@xterm/addon-web-links'),
                    import('@xterm/addon-image')
                ]);

                const xterm = new Terminal({
                    allowTransparency: false,
                    cursorBlink: true,
                    cursorStyle: 'block',
                    fontFamily: '"Fira Code VF", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
                    fontSize: 14,
                    fontWeight: 400,
                    fontWeightBold: 500,
                    lineHeight: 1.2,
                    scrollback: 1000,
                    theme: themes.dark,
                    cols: 80,
                    rows: 24,
                    wordWrap: false,
                    convertEol: true,
                    rightClickSelectsWord: true,
                });

                // IMPORTANT: Set the sessionId on the terminal instance from props
                xterm.sessionId = terminalProps.sessionId;

                // Load addons
                const fitAddon = new FitAddon();
                const webLinksAddon = new WebLinksAddon();
                const imageAddon = new ImageAddon({ enableSizeReports: false });

                xterm.loadAddon(fitAddon);
                xterm.loadAddon(webLinksAddon);
                xterm.loadAddon(imageAddon);

                xterm.open(terminalRef.current!);
                fitAddon.fit();

                // Handle resize
                const handleResize = () => {
                    if (fitAddon && terminalRef.current) {
                        const containerRect = terminalRef.current.getBoundingClientRect();
                        let maxWidth = Math.min(containerRect.width - 16, 800);
                        let maxHeight = Math.min(containerRect.height - 16, 500);

                        if (maxWidth > 0 && maxHeight > 0) {
                            fitAddon.fit();
                            const { rows, cols } = xterm;

                            // Constrain terminal size
                            let constrainedCols = Math.min(cols, 120);
                            let constrainedRows = Math.min(rows, 40);

                            if (cols !== constrainedCols || rows !== constrainedRows) {
                                xterm.resize(constrainedCols, constrainedRows);
                            }

                            onResize?.(xterm.sessionId, constrainedRows, constrainedCols);
                        }
                    }
                };

                // Initial fit and resize handler
                handleResize();
                window.addEventListener("resize", handleResize);

                // Handle user input
                const utf8Encoder = new TextEncoder();
                xterm.onData((data: string) => {
                    const dataArray = utf8Encoder.encode(data);
                    console.log(`[XTerm Debug] Input received:`, {
                        data: Array.from(dataArray),
                        text: data,
                        charCodes: data.split('').map(c => c.charCodeAt(0))
                    });
                    console.log(`[XTerm Debug] xterm.sessionId:`, xterm.sessionId);
                    console.log(`[XTerm Debug] xterm object:`, xterm);
                    if (xterm.sessionId) {
                        onInput(xterm.sessionId, Array.from(dataArray));
                    } else {
                        console.error(`[XTerm Debug] ERROR: xterm.sessionId is undefined or null!`);
                    }
                });

                xterm.onBinary((data: string) => {
                    const dataArray = new TextEncoder().encode(data);
                    console.log(`[XTerm Debug] Binary input received:`, {
                        data: Array.from(dataArray),
                        text: data
                    });
                    console.log(`[XTerm Debug] xterm.sessionId (binary):`, xterm.sessionId);
                    if (xterm.sessionId) {
                        onInput(xterm.sessionId, Array.from(dataArray));
                    } else {
                        console.error(`[XTerm Debug] ERROR: xterm.sessionId is undefined or null in binary handler!`);
                    }
                });

                terminalInstanceRef.current = xterm;
                fitAddonRef.current = fitAddon;
                setLoaded(true);

                return () => {
                    console.log(`🧹 Cleaning up terminal ${xterm.sessionId}`);
                    window.removeEventListener("resize", handleResize);
                    if (terminalInstanceRef.current) {
                        terminalInstanceRef.current.dispose();
                        terminalInstanceRef.current = null;
                    }
                };
            } catch (error) {
                console.error('Failed to initialize terminal:', error);
            }
        };

        initializeTerminal();
    }, [terminalProps.sessionId, isClient, onInput, onResize]);

    // Listen for terminal output
    useEffect(() => {
        if (!loaded) return;

        const setupListener = async () => {
            unlistenFn.current = await listen(
                `riterm://terminal-output-${terminalProps.sessionId}`,
                (event) => {
                    const { data } = event.payload;
                    const text = new TextDecoder().decode(new Uint8Array(data));
                    console.log(`[XTerm Debug] Remote output received:`, {
                        output: text.substring(0, 100),
                        charCodes: text.split('').map(c => c.charCodeAt(0))
                    });

                    if (terminalInstanceRef.current) {
                        terminalInstanceRef.current.write(text);
                    }
                }
            );
        };

        setupListener();

        return () => {
            if (unlistenFn.current) {
                unlistenFn.current();
            }
        };
    }, [terminalProps.sessionId, loaded]);

    // Handle rename
    const handleRename = useCallback(() => {
        if (isEditing) {
            onRename(terminalProps.sessionId, editName.trim() || undefined);
            setIsEditing(false);
        } else {
            setIsEditing(true);
            setEditName(terminalProps.name || '');
        }
    }, [isEditing, editName, terminalProps.sessionId, terminalProps.name, onRename]);

    const handleRenameKeyDown = useCallback((e: React.KeyboardEvent) => {
        if (e.key === 'Enter') {
            handleRename();
        } else if (e.key === 'Escape') {
            setIsEditing(false);
            setEditName(terminalProps.name || '');
        }
    }, [handleRename, terminalProps.name]);

    // Get status color
    const getStatusColor = useCallback(() => {
        switch (terminalProps.status) {
            case 'active':
                return 'text-green-500';
            case 'closed':
            case 'terminated':
                return 'text-red-500';
            case 'error':
                return 'text-red-600';
            default:
                return 'text-gray-500';
        }
    }, [terminalProps.status]);

    if (!isClient) {
        return (
            <div className="flex flex-col h-full bg-gray-950 rounded-lg overflow-hidden shadow-xl">
                {/* Terminal Header */}
                <div className="bg-gray-800 px-3 py-2 border-b border-gray-700">
                    <div className="flex items-center justify-between">
                        <div className="flex items-center space-x-2">
                            <div className="flex items-center space-x-1">
                                <div className="w-3 h-3 bg-red-500 rounded-full"></div>
                                <div className="w-3 h-3 bg-yellow-500 rounded-full"></div>
                                <div className="w-3 h-3 bg-green-500 rounded-full"></div>
                            </div>
                            <div className="h-4 w-px bg-gray-600"></div>
                            <div className="text-sm font-medium text-gray-300 truncate">
                                Terminal {terminalProps.sessionId}
                            </div>
                        </div>
                        <div className="flex items-center space-x-2">
                            <div className="flex items-center space-x-1">
                                <div className="w-2 h-2 bg-yellow-500 rounded-full animate-pulse"></div>
                                <span className="text-xs text-gray-400">Loading...</span>
                            </div>
                        </div>
                    </div>
                </div>

                {/* Terminal Area */}
                <div className="flex-1 flex items-center justify-center bg-gray-900">
                    <div className="text-center">
                        <div className="w-8 h-8 border-2 border-gray-600 border-t-blue-500 rounded-full animate-spin mx-auto mb-3"></div>
                        <div className="text-gray-400 text-sm">Initializing terminal...</div>
                    </div>
                </div>
            </div>
        );
    }

    return (
        <div className="flex flex-col h-full bg-gray-950 rounded-lg overflow-hidden shadow-xl">
            {/* Terminal Header */}
            <div className="bg-gray-800 px-3 py-2 border-b border-gray-700">
                <div className="flex items-center justify-between">
                    <div className="flex items-center space-x-2">
                        <div className="flex items-center space-x-1">
                            <div className="w-3 h-3 bg-red-500 rounded-full hover:bg-red-400 transition-colors cursor-pointer"></div>
                            <div className="w-3 h-3 bg-yellow-500 rounded-full hover:bg-yellow-400 transition-colors cursor-pointer"></div>
                            <div className="w-3 h-3 bg-green-500 rounded-full hover:bg-green-400 transition-colors cursor-pointer"></div>
                        </div>
                        <div className="h-4 w-px bg-gray-600"></div>
                        {isEditing ? (
                            <input
                                type="text"
                                value={editName}
                                onChange={(e) => setEditName(e.target.value)}
                                onKeyDown={handleRenameKeyDown}
                                onBlur={handleRename}
                                className="bg-gray-700 text-white px-2 py-1 rounded text-sm"
                                placeholder="Terminal name..."
                                autoFocus
                            />
                        ) : (
                            <span
                                className="text-white cursor-pointer hover:text-gray-300"
                                onClick={handleRename}
                                title="Click to rename"
                            >
                                {terminalProps.name || terminalProps.sessionId}
                            </span>
                        )}
                        <span className={`text-xs ${getStatusColor()}`}>
                            ({terminalProps.status})
                        </span>
                    </div>

                    <div className="flex items-center space-x-2">
                        <span className="text-xs text-gray-400">
                            {terminalProps.size.rows}x{terminalProps.size.cols}
                        </span>
                        <button
                            onClick={() => onClose(terminalProps.sessionId)}
                            className="text-red-400 hover:text-red-300 transition-colors"
                            title="Close terminal"
                        >
                            ✕
                        </button>
                    </div>
                </div>
            </div>

            {/* Terminal Area */}
            <div className="flex-1 flex flex-col min-h-0">
                <div
                    ref={terminalRef}
                    className="flex-1 p-2 sm:p-3 overflow-x-hidden overflow-y-auto transition-all duration-200"
                    style={{
                        minHeight: "300px",
                        width: "100%",
                        backgroundColor: themes.dark.background,
                        fontSize: '14px'
                    }}
                />
            </div>
        </div>
    );
}